package org.benetech.util;

import java.io.File;

import org.benetech.beans.error.ValidationError;
import org.benetech.beans.error.XMLValidationError;
import org.benetech.beans.error.ValidationError.Severity;
import org.benetech.collections.ListMap;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * An error handler that can be plugged into the SAX Parser, and which builds a
 * list of violations as events are fired by SAX during parsing.
 * @author Reuben Firmin
 */
public final class ViolationCollatingErrorHandler implements ErrorHandler {

    private final ListMap<File, ValidationError> violations =
        new ListMap<File, ValidationError>();

    private File errorContext;

    /**
     * Default constructor.
     */
    public ViolationCollatingErrorHandler() {
    	// empty
    }

    /**
     * Set the error context, i.e. a string used in construction of the
     * messages mostly likely identifying the file being parsed.
     * @param context Never null
     */
    public void setErrorContext(final File context) {
        this.errorContext = context;
    }

    /**
     * Get the map of violations collected during processing, mapped against
     * the error context.
     * @return not null.
     */
    public ListMap<File, ValidationError> getViolations() {
        return violations;
    }

    /**
     * Clear violations. Useful for reuse.
     */
    public void clearViolations() {
    	violations.clear();
    }

    /**
     * {@inheritDoc}
     */
    public void error(final SAXParseException exception)
        throws SAXException
    {
        violations.put(errorContext,
                new XMLValidationError(exception.getLineNumber(),
                exception.getColumnNumber(), exception.getMessage(),
                exception.getSystemId(), errorContext,
                    Severity.WARNING));
    }

    /**
     * {@inheritDoc}
     */
    public void fatalError(final SAXParseException exception)
        throws SAXException
    {
        violations.put(errorContext,
                new XMLValidationError(exception.getLineNumber(),
                exception.getColumnNumber(), exception.getMessage(),
                exception.getSystemId(), errorContext,
                    Severity.ERROR));
    }

    /**
     * {@inheritDoc}
     */
    public void warning(final SAXParseException exception)
        throws SAXException
    {
        violations.put(errorContext,
                new XMLValidationError(exception.getLineNumber(),
                exception.getColumnNumber(), exception.getMessage(),
                exception.getSystemId(), errorContext, Severity.INFO));
    }
}
